package slice

import "errors"

// RemoveIndex 用泛型实现删除切片中指定位置的元素
func RemoveIndex[T any](slice []T, index int) ([]T, error) {
	if index < 0 || index >= len(slice) {
		return nil, errors.New("下标超出切片长度")
	}
	newSlice := append(slice[:index], slice[index+1:]...)
	// 删除完判断是否需要缩容
	newSlice = Shrink(newSlice)
	return newSlice, nil
}

// RemoveIndex2 另一种实现方式
func RemoveIndex2[T any](slice []T, index int) ([]T, error) {
	if index < 0 || index >= len(slice) {
		return nil, errors.New("下标超出切片长度")
	}
	var newSlice = make([]T, 0)
	for i, v := range slice {
		if i != index {
			newSlice = append(newSlice, v)
		}
	}
	// 删除完判断是否需要缩容
	newSlice = Shrink(newSlice)
	return newSlice, nil
}

// Shrink 实现切片缩容
// 目前实现的逻辑为：判断容量是否大于64，如果是则判断容量是否小于总长度的1/4，如果是则缩容至1/2
func Shrink[T any](slice []T) []T {
	needShrink := isNeedShrink(slice)
	if needShrink {
		newSlice := make([]T, 0, cap(slice)/2)
		newSlice = append(newSlice, slice...)
		return newSlice
	}
	return slice
}

// isNeedShrink 是否需要缩容
func isNeedShrink[T any](slice []T) bool {
	ca := cap(slice)
	le := len(slice)
	// 容量小于64不缩容
	if ca < 64 {
		return false
	}
	if le < ca/4 {
		return true
	} else {
		return false
	}
}
